package com.apes.fn.scm.retailOrder.service.account.retail;

import com.apes.fn.scm.retailOrder.service.account.RetailAccountData;
import com.apes.fn.scm.retailOrder.service.account.BackBatchAndSupplierService;
import com.apes.fn.server.servicePlan.model.ServicePlan;
import com.apes.fn.server.servicePlan.model.ServicePlanItem;
import com.apes.fn.server.servicePlan.service.ServicePlanceService;
import com.apes.framework.api.SpringManager;
import com.apes.framework.util.MapUtil;
import com.apes.scm.account.tax.model.Tax;
import com.apes.scm.account.tax.service.TaxService;
import com.apes.scm.contract.model.Contract;
import com.apes.scm.contract.service.ContractService;
import com.apes.scm.masterdata.frame.model.Dept;
import com.apes.scm.masterdata.party.model.PartyRole;
import com.apes.scm.sal.saleOrder.SaleOrder;
import com.apes.scm.sal.saleOrder.SaleOrderItem;
import com.apes.scm.sal.saleOrder.SaleOrderItemRepository;
import com.apes.scm.voucher.model.Voucher;
import com.apes.scm.voucher.model.VoucherItem;
import com.apes.scm.voucher.service.BusinessType;
import com.apes.scm.voucher.service.VoucherType;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 内协凭证服务
 * @Author wuq
 * @Date 2021-7-22
 */
@RetailAccount(value = "innerHelp", name = "内协凭证服务")
@Service
public class InnerHelpVoucherService extends BackBatchAndSupplierService {

    @Autowired
    private ContractService contractService;
    @Autowired
    private ServicePlanceService servicePlanceService;
    @Autowired
    private TaxService taxService;

    public void process(RetailAccountData retailAccountData) {
        ServicePlan servicePlan = retailAccountData.getServicePlan();
        List<ServicePlanItem> servicePlanItemList = retailAccountData.getServicePlanItems();
        Dept serviceDept = retailAccountData.getDept();

        // 创建分销单
        createSaleOrderVoucher(servicePlan, servicePlanItemList, serviceDept);

        // 门店的采购凭证
        createStorePurchaseVoucher(servicePlan, servicePlanItemList, serviceDept);
    }

    private void createSaleOrderVoucher(ServicePlan servicePlan, List<ServicePlanItem> servicePlanItemList, Dept serviceDept){
        PartyRole company = servicePlan.getBelongDept().getCompany();   // 门店公司
        PartyRole supplier = serviceDept.getCompany();                  // 基地公司

        List<ServicePlanItem> servicePlanItems = getBaseServicePlanItems(servicePlanItemList);
        List array = MapUtil.mapped(servicePlanItems);
        invoke("innerServicePlan.create.autoReturn", array);     // 自动归还

        // 组装数据，创建内协分销单
        Map param = MapUtil.mapper("deptId", serviceDept.getId(), "companyId", supplier.getId(),
                "customerId", company.getParty().getPatyRoleByType("Customer").getId(),
                "items", array);
        List<SaleOrder> saleOrderList = invoke("innerServicePlan.create.saleOrder", param);  // 创建销售订单（自动审核）
        saleOrderList.forEach(saleOrder -> {
            // 销售订单商品出库
            invoke("saleOrderFlow.create.productOutput", MapUtil.mapped(saleOrder));

            // 创建销售凭证以及账单
            invoke("saleOrderFlow.create.voucher", MapUtil.mapped(saleOrder));
        });
    }

    /**
     * 通过门店方案找到基地方案明细
     * @param servicePlanItemList 门店方案明细
     * @return List<ServicePlanItem>
     */
    private List<ServicePlanItem> getBaseServicePlanItems(List<ServicePlanItem> servicePlanItemList) {
        // 找到基地的服务方案明细
        List<ServicePlanItem> servicePlanItems = new ArrayList<>();
        servicePlanItemList.stream()
                .filter(servicePlanItem -> "inner".equals(servicePlanItem.getAssistType().getCode())
                        && servicePlanItem.getTerminationDate() == null && servicePlanItem.isServiceState())
                .forEach(
                        planItem -> {
                            ServicePlanItem basePlanItem = servicePlanceService.findCBPForServicePlan(planItem);
                            if (basePlanItem == null)
                                throw new RuntimeException("创建整单内协方案基地分销单时，根据门店方案未找到对应内协门店方案，门店方案号为：" + planItem.getId());
                            servicePlanItems.add(basePlanItem);
                        }
                );
        if (servicePlanItems.size() == 0) throw new RuntimeException("创建整单内协方案基地分销单，在新框架中没有到找到对应的基地方案。");
        return servicePlanItems;
    }

    private Voucher createStorePurchaseVoucher(ServicePlan servicePlan, List<ServicePlanItem> servicePlanItemList, Dept serviceDept){
        PartyRole company = servicePlan.getBelongDept().getCompany();   // 门店公司
        PartyRole supplier = serviceDept.getCompany();

        Voucher voucher = new Voucher();
        voucher.setBusinessType(BusinessType.PURCHASE_ORDER);

        voucher.setDept(servicePlan.getBelongDept());
        voucher.setCompany(servicePlan.getBelongDept().getCompany());
        voucher.setPartner(supplier.getParty().getPartyRoleByType("Supplier")); // 这里不用区分是否为 1001

        // 查询合同 （目前采购结算按照合同）
        Contract contract = contractService.getContract(servicePlan.getBelongDept(), voucher.getPartner(), "distribution", "supplier", "服务内协业务");
        voucher.setContract(contract);

        voucher.setInventoryMode(voucher.getContract().getCooperation().getInventoryMode());     //设置库存模式：寄售
        voucher.setAccountingMethod(voucher.getContract().getCooperation().getAccountingMethod());  // 核算方式：采购价
        voucher.setClassification(VoucherType.WHOLE_INNER_HELP);
        voucher.setCustomerExpand(servicePlan.getFnCustomerExpand().getId());

        voucher.setClerk(servicePlan.getConfirmUid()); //业务员
        voucher.setScene(servicePlan.getScene());
        voucher.setOrigin(servicePlan.getId());
        voucher.setOriginBusinessType(ServicePlan.class.getSimpleName());
        voucher.setSource(servicePlan.getId());
        voucher.setSourceBusinessType(ServicePlan.class.getSimpleName());

        final boolean flag = true;
        voucher.setVoucherItems(
                servicePlanItemList.stream()
                        .filter(servicePlanItem -> "inner".equals(servicePlanItem.getAssistType().getCode())
                                && servicePlanItem.getTerminationDate() == null && servicePlanItem.isServiceState())
                        .map(servicePlanItem -> {
                            VoucherItem voucherItem = new VoucherItem();
                            voucherItem.setProduct(servicePlanItem.getProduct());
                            voucherItem.setPriceUnit(servicePlanItem.getPriceCostUnitInTax());
                            voucherItem.setOwner(company);

                            Tax tax = taxService.getPurchaseTax(company, supplier, servicePlanItem.getProduct());
                            voucherItem.setTax(tax);

                            // 设置为销售的单位以及数量
                            voucherItem.setUom(servicePlanItem.getUom());
                            voucherItem.setProductQty(servicePlanItem.getSaleQty() - servicePlanItem.getQtyEnd());
                            voucherItem.setOriginItemId(servicePlanItem.getId());
                            voucherItem.setSourceItemId(servicePlanItem.getId());

                            // 采购价格取带安成本单价
                            if ("1001".equals(supplier.getId())) {
                                voucherItem.setPriceUnit(servicePlanItem.getPriceCostUnitInTax());
                            } else if ("1007".equals(supplier.getId())) {
                                voucherItem.setPriceUnit(servicePlanItem.getPlatformPriceCosInTax());
                            }
                            voucherItem.setInnerSalePriceUnit(servicePlanItem.getPriceCostUnitInTax());    // 公司间交易价

                            if (flag) { // 以及创建了分销单
                                ServicePlanItem basePlanItem = servicePlanceService.findCBPForServicePlan(servicePlanItem);
                                SaleOrderItem saleOrderItem = SpringManager.getBean(SaleOrderItemRepository.class).findFirstByOriginItemId(basePlanItem.getId());
                                if (saleOrderItem == null) throw new RuntimeException("整单内协写入采购凭证时，未找到销售订单明细行号");
                                voucherItem.setSupplierRef(saleOrderItem.getId());
                                voucherItem.setPriceUnit(saleOrderItem.getPriceUnit());      // 产生跨公司交易之后，取分销单上面的价格
                            }
                            return voucherItem;
                        }).collect(Collectors.toSet())
        );
        voucher = invoke("voucher.create", MapUtil.mapped(voucher));

        // 回写方案明细批次以及供应商信息
        sendServicePlanBathAndSupplier(voucher);

        invoke("invoice.create", MapUtil.mapped(invoke("voucher.flow.invoice", MapUtil.mapped(voucher))));
        return voucher;
    }
}
